package jmind.core.aspect;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jmind.base.util.IpUtil;

import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 *  * 性能拦截器，查询接口响应时间，调用次数
 *   默认 按 org.perf4j.TimingLogger 名字记录日志
 *   
 *   @Profiled 注解统计方法性能
 *   @Profiled(tag = "search({$0},{$1},{$2})")  
 *   http://www.verydemo.com/demo_c441_i122900.html
 *    http://www.blogjava.net/yangpingyu/archive/2012/04/19/375267.html
 * @author xieweibo
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/hades/**"   />
      <mvc:exclude-mapping path="/hades/product/info"/>
            <mvc:exclude-mapping path="/hades/paymentTypes"/>
            <mvc:exclude-mapping path="/hades/paypal/client/notify"/> 
            <bean class="com.letv.boss.api.controller.interceptors.SignatureInterceptor"></bean>
        </mvc:interceptor> 
          
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <mvc:exclude-mapping path="/static/**"/>
            <bean class="com.letv.commons.aop.PerformanceInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
 */
public class PerformanceInterceptor extends HandlerInterceptorAdapter {

    private static ThreadLocal<StopWatch> local = new ThreadLocal<StopWatch>();

    private final Logger switchLogger = LoggerFactory.getLogger("org.perf4j.TimingLogger");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        StopWatch stopWatch = new Slf4JStopWatch("shell");
        local.set(stopWatch);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        StopWatch watch = local.get();
        if (watch != null) {
            watch.stop(generateOperatonIdendifier(request, watch.getElapsedTime()));
            local.remove();
        }
    }

    private String generateOperatonIdendifier(HttpServletRequest request, long exeTime) {
        StringBuilder sb = new StringBuilder(64);

        // 方法
        String method = request.getMethod();
        sb.append(method);

        sb.append('|');

        // URI
        if (switchLogger.isTraceEnabled()) { // 如果是trace级别，统计到具体的URI
            sb.append(request.getRequestURL());
            sb.append('|');
            String clientIp = IpUtil.getIp(request);
            sb.append(clientIp);
            sb.append('|');
            sb.append(request.getHeader("User-Agent"));

        } else { // 按URI pattern匹配，方便汇总
            sb.append(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE));
        }

        // 记录慢得url,
        if (exeTime > 400) {
            sb.append("|SLOW");
        }

        return sb.toString();
    }

}
